﻿
using HBase;
using System;
using System.Collections.Generic;
namespace hCommand {

    public class RailRange {

        public int taskNo = 0;
        public int rgvId;
        public int begin;
        public int x1;
        public int x2;
        public RailRange(int taskNo ,int x1 ,int x2) {
            begin = x1;
            if( x1 < x2 ) {
                this.x1 = x1;
                this.x2 = x2;
            } else {
                this.x1 = x2;
                this.x2 = x1;
            }
            this.taskNo = taskNo;
        }
    }

    public class CommonRailDodge {
        private List<int> taskNoList = new List<int>();
        private MyDict<int ,RailRange> taskRangeDict = new MyDict<int ,RailRange>();


        private int gap = 2000;//两车间的安全距离


        private RailRange rr1 = null;
        private RailRange rr2 = null;

        private int middleX = 0;
        private MyDict<int ,int> pos2X = new MyDict<int ,int>();
        public CommonRailDodge(params int[] list) {
            if( list.Length % 2 == 1 ) {
                throw new Exception("addPosX参数长度异常");
            }
            int max = 0;
            int min = int.MaxValue;
            for( int i = 0;i < list.Length; ) {
                int pos = list[i++];
                int x = list[i++];
                pos2X.addOverride(pos ,x);
                max = Math.Max(max ,x);

                min = Math.Min(min ,x);
            }
            middleX = (max + min) / 2;

        }

        //1号rgv的在定位偏小的地方
        public List<RailRange> getTask(int taskNo ,int x11 ,int x12 ,int taskNo2 ,int x21 ,int x22 ,List<BaseTask> taskList) {
            bool idle1 = taskNo == 0;
            bool idle2 = taskNo2 == 0;
            rr1 = new RailRange(taskNo ,x11 ,x12);
            rr2 = new RailRange(taskNo2 ,x21 ,x22);

            removeTask(taskNo);
            removeTask(taskNo2);
            uploadTask(taskList);

            RailRange rr = selectTask(idle1 ,idle2);

            if( rr == null ) {
                return null;
            }
            checkDodge(rr ,idle1 ,idle2 ,x21 ,x12);

            return new List<RailRange>() { rr1 ,rr2 };
        }

        void checkDodge(RailRange rr ,bool idle1 ,bool idle2 ,int x21 ,int x12) {
            if( rr.rgvId == 1 ) {
                rr1 = rr;
                if( idle2 && x21 - rr.x2 < gap ) {
                    rr2 = new RailRange(0 ,0 ,rr.x2);
                    rr2.rgvId = 2;
                }
            } else {
                rr2 = rr;
                if( idle1 && rr.x1 - x12 < gap ) {
                    rr1 = new RailRange(0 ,0 ,rr.x1);
                    rr1.rgvId = 1;
                }
            }

        }

        RailRange idle1Only() {
            int max = rr2.x1;
            for( int i = 0;i < taskNoList.Count;i++ ) {
                RailRange check = taskRangeDict[taskNoList[0]];
                if( rr1.taskNo == check.taskNo ) {
                    continue;
                }
                if( max - check.x2 > gap ) {
                    check.rgvId = 1;
                    return check;
                }

            }
            return null;

        }

        RailRange idle2Only() {
            int min = rr1.x2;
            for( int i = 0;i < taskNoList.Count;i++ ) {
                RailRange check = taskRangeDict[taskNoList[0]];
                if( rr2.taskNo == check.taskNo ) {
                    continue;
                }
                if( check.x1 - min > gap ) {
                    check.rgvId = 2;
                    return check;
                }

            }
            return null;

        }

        private RailRange selectTask(bool idle1 ,bool idle2) {

            if( idle1 && idle2 ) {
                RailRange rr = taskRangeDict[taskNoList[0]];
                if( (rr.x1 + rr.x2) / 2 < middleX ) {
                    rr.rgvId = 1;
                } else {
                    rr.rgvId = 2;
                }
                return rr;

            } else if( idle1 ) {
                return idle1Only();
            } else if( idle2 ) {
                return idle2Only();
            }


            return null;

        }
        //执行中或者待执行
        private void uploadTask(List<BaseTask> taskList) {
            for( int i = 0;i < taskNoList.Count;i++ ) {
                int taskNo = taskNoList[i];
                bool has = false;
                foreach( BaseTask bt in taskList ) {
                    if( taskNo == bt.taskNo ) {
                        has = true;
                    }
                }
                if( !has ) {
                    removeTask(taskNo);
                }

            }


            foreach( BaseTask task in taskList ) {
                if( taskNoList.Contains(task.taskNo) ) {
                    continue;
                }

                if( rr1 != null && rr1.taskNo == task.taskNo ) {
                    continue;
                }

                if( rr2 != null && rr2.taskNo == task.taskNo ) {
                    continue;
                }
                taskNoList.Add(task.taskNo);
                taskRangeDict.Add(task.taskNo ,new RailRange(task.taskNo ,pos2X[task.src] ,pos2X[task.des]));

            }

        }
        //执行结束
        private void removeTask(int taskNo) {
            if( taskNoList.Contains(taskNo) ) {
                taskNoList.Remove(taskNo);
            }

            if( taskRangeDict.ContainsKey(taskNo) ) {
                taskRangeDict.remove(taskNo);
            }
        }


    }



}
